package com.wanmait.schedule.controller;

import com.wanmait.schedule.entity.Permission;
import com.wanmait.schedule.entity.Role;
import com.wanmait.schedule.entity.Student;
import com.wanmait.schedule.entity.Teacher;
import com.wanmait.schedule.service.RoleService;
import com.wanmait.schedule.service.StudentService;
import com.wanmait.schedule.service.TeacherService;
import com.wanmait.schedule.util.AjaxResult;
import com.wanmait.schedule.util.JWTUtils;
import com.wanmait.schedule.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.Duration;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
@RestController
public class CommController {

    @Resource
    private StudentService studentService;
    @Resource
    private TeacherService teacherService;
    @Autowired
    private RoleService roleService;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private RedisUtil redisUtil;

    @PostMapping("/web/login")
    public AjaxResult login(@RequestBody Student student,@RequestParam("radio") Integer radio,String code,String codeKey){
        if(!StringUtils.hasText(code)||!StringUtils.hasText(codeKey)){
            return AjaxResult.error(10000,"验证码错误");
        }
        String rightCode = (String) redisTemplate.opsForValue().get("codeKey:"+codeKey);
        if(!code.equalsIgnoreCase(rightCode)){
            return AjaxResult.error(10000,"验证码错误");
        }
        //String ip = request.getRemoteAddr();//远程客户端IP地址  request.getLocalAddr();服务器本地IP地址
        //admin.setLoginIp(ip);
        if(radio == 1){
            Student loginStudent = studentService.login(student.getUsername(), student.getPassword());
            if(loginStudent==null){
                return AjaxResult.error(10001,"登录失败");
            }
            else{
                //生成token
                Map<String,String> claims = new HashMap<>();
                claims.put("username",loginStudent.getUsername());
                claims.put("name",loginStudent.getName());
                String token = JWTUtils.createToken(loginStudent.getId()+"",60,loginStudent.getPassword(),claims);
                loginStudent.setPassword(null);
                return AjaxResult.success("登录成功").put("token",token).put("student",loginStudent);
            }
        }
        else{
            Teacher teacher = new Teacher();
            teacher.setUsername(student.getUsername());
            teacher.setPassword(student.getPassword());
            Teacher loginTeacher = teacherService.login(teacher.getUsername(), teacher.getPassword());
            if(loginTeacher==null){
                return AjaxResult.error(10001,"登录失败");
            }
            else{
                //生成token
                Map<String,String> claims = new HashMap<>();
                claims.put("username",loginTeacher.getUsername());
                claims.put("name",loginTeacher.getName());
                String token = JWTUtils.createToken(loginTeacher.getId()+"",60,loginTeacher.getPassword(),claims);
                loginTeacher.setPassword(null);
                return AjaxResult.success("登录成功").put("token",token).put("teacher",loginTeacher);
            }
        }
    }

    @ResponseBody
    @RequestMapping("/checkCode")
    public AjaxResult checkCode(String code,String codeKey,HttpServletRequest request){
//        String rightCode = stringRedisTemplate.opsForValue().get(codeKey);
//        if(rightCode!=null && code!=null&& rightCode.equalsIgnoreCase(code)){
//            return AjaxResult.success("验证码校验成功");
//        }
//        return AjaxResult.error("验证码错误");
        return null;
    }
    @RequestMapping("/code")
    @ResponseBody
    public AjaxResult createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 创建缓存图片：指定宽
        int width = 90, height = 30;
        //参数：宽，高，图片模式
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 2. 获取画笔对象
        Graphics graphics = bufferedImage.getGraphics();
        // 3. 设置画笔颜色
        graphics.setColor(Color.WHITE);
        // 4. 填充矩形区域
        graphics.fillRect(0, 0, width, height);
        // 5. 从字符数组中随机得到字符
        char[] arr = {'A', 'B', 'C', 'D', 'E','F','G','H','J','K','M','N','P','Q','R','S','T','U','V', 'W','X','Y','Z',
                'a','b','c','d','e','f','g','h','j','k','l','m','n', 'p','q','r','s','t','u','v','w','x','y','z',
                '0', '1', '2', '3', '4', '5', '6','7','8','9'};
        // 6. 循环4次，画4个字符
        String code="";
        for (int i = 0; i < 4; i++) {
            int index = random.nextInt(arr.length);
            char c = arr[index];  //随机得到一个字符
            code = code+c;
            // 7. 设置字的颜色为随机
            graphics.setColor(getRandomColor());
            // 8. 设置字体，大小为18。参数：字体，样式，大小
            graphics.setFont(new Font(Font.DIALOG, Font.BOLD + Font.ITALIC, 19));
            // 9. 将每个字符画到图片，x增加，y不变。
            //参数：画字符，x位置，y位置。把c从字符转成字符串
            graphics.drawString(String.valueOf(c), 10 + (i * 20), 20);
        }
        //干扰线
        for (int i = 0; i < 10; i++) {
            // 10. 线的位置是随机的，x范围在width之中，y的范围在height之中。
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            // 11. 画8条干扰线，每条线的颜色不同
            graphics.setColor(getRandomColor());
            graphics.drawLine(x1, y1, x2, y2);
        }
        // 12. 将缓存的图片输出到响应输出流中
        //参数：图片对象，图片格式，输出流
        //ImageIO.write(img, "jpg", response.getOutputStream());
        //bufferedImage 是生成的图片
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        //参数内容为图片，图片后缀，流
        ImageIO.write(bufferedImage, "jpg", stream);
        byte[] bytes = stream.toByteArray();//转换成字节
        Base64.Encoder encoder = Base64.getEncoder();
        //转换成base64串
        String base64 = encoder.encodeToString(bytes).trim();
        //删除 \r\n
        base64 = base64.replaceAll("\n", "").replaceAll("\r", "");
        //生成的验证码放到redis中一份
        String codeKey = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set("codeKey:"+codeKey,code,2, TimeUnit.MINUTES);
        //给客户端返回数据，携带验证码图片，键名
        return AjaxResult.success().put("codeKey",codeKey).put("codeImg","data:image/jpg;base64,"+base64);
    }
    private Random random = new Random();

    /**
     写一个方法随机获取颜色
     */
    private Color getRandomColor() {
        //随机生成0-255之间整数
        int red = random.nextInt(256);
        int green = random.nextInt(256);
        int blue = random.nextInt(256);
        //参数：红，绿，蓝 (0-255)
        return new Color(red, green, blue);
    }

    //后台管理员登录
    @PostMapping("manage/login")
    public AjaxResult manageLogin(@RequestBody Teacher teacher,HttpServletRequest request){
        String ip = request.getRemoteAddr();
        teacher.setLoginIp(ip);
        Teacher loginTeacher = teacherService.login(teacher);
        if(loginTeacher==null){
            return AjaxResult.error(10001,"登陆失败");
        }
        //生成token
        Map<String,String> clamis = new HashMap<>();
        clamis.put("username",loginTeacher.getUsername());
        clamis.put("name",loginTeacher.getName());
        String token = JWTUtils.createToken(loginTeacher.getId()+"",60,loginTeacher.getPassword(),clamis);

        //把教师存到缓存中
        redisUtil.set("auth:"+token,loginTeacher,3600);

        loginTeacher.setPassword(null);
//        System.out.println(loginTeacher.getLoginTime());

/*        List<Role> roleList = teacherService.findRoles(loginTeacher.getId());
        List<Integer> roleIdList = roleList.stream().map(role -> role.getId()).collect(Collectors.toList());
        List<Permission> permissions = roleService.findRoles(roleIdList);
        Set<String> permissionSet = permissions.stream().map(permission -> permission.getPerm()).collect(Collectors.toSet());*/

        return AjaxResult.success("登陆成功").put("token",token).put("loginTeacher",loginTeacher)/*.put("permissionSet",permissionSet)*/;
    }


    //通过控制器统一抛出异常，走统一的异常处理
    @RequestMapping("/errorToken")
    public void error(@RequestAttribute Exception exception) throws Exception{
        throw exception;
    }

    //登陆之后获得所有权限
    @RequestMapping("manage/findAllPermission")
    public AjaxResult findAllPermission(@RequestAttribute("teacher") Teacher teacher){
        //角色集合
        List<Role> roleList = teacherService.findRoles(teacher.getId());
      /*  Set<String> roleSet = roleList.stream().map(role -> role.getRole()).collect(Collectors.toSet());
        authorizationInfo.setRoles(roleSet);*/
        //角色id集合
        List<Integer> roleIdList = roleList.stream().map(role -> role.getId()).collect(Collectors.toList());
        //权限集合
        List<Permission> permissions = roleService.findRoles(roleIdList);

        Set<String> permissionSet = permissions.stream().map(permission -> permission.getPerm()).collect(Collectors.toSet());

        return AjaxResult.success("成功",permissionSet);
    }
}
